package com.cbh.amadeus.client.config;

import com.cbh.amadeus.client.core.Subscriber;
import com.cbh.amadeus.client.factory.MessageAbandonFactory;
import com.cbh.amadeus.client.factory.MessageResendFactory;
import com.cbh.amadeus.client.receiver.component.SubscriberComponent;
import com.cbh.amadeus.client.receiver.consumer.MessageConsumerProxy;
import com.cbh.amadeus.client.receiver.consumer.MessageHolderWrap;
import com.cbh.amadeus.client.receiver.register.MessageRegisterProxy;
import com.cbh.amadeus.client.receiver.service.MessageHolder;
import com.cbh.amadeus.client.receiver.tool.MessagePlaceModelTool;
import com.cbh.amadeus.client.receiver.tool.MessageRepositoryModelTool;
import com.cbh.amadeus.client.receiver.tool.MessageResultModelTool;
import com.cbh.amadeus.client.receiver.tool.impl.DefaultMessageModelRepositoryTool;
import com.cbh.amadeus.client.receiver.tool.impl.DefaultMessagePlaceModelTool;
import com.cbh.amadeus.client.receiver.tool.impl.DefaultMessageResultModelTool;
import com.cbh.amadeus.client.utils.AmadeusMessageTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * @author ChenBiHui
 * @date 2025/4/27
 */
@Slf4j
@Configuration
@ConditionalOnBean({SubscriberConfig.class})
public class SubscriberAutoConfiguration {

    @Bean
    public Subscriber subscriber() {
        Subscriber subscriber = new Subscriber();
        log.info("===== Subscriber initial finish =====");
        return subscriber;
    }

    @Bean
    public SubscriberComponent subscriberComponent() {
        SubscriberComponent subscriberComponent = new SubscriberComponent();
        log.info("===== SubscriberComponent initial finish =====");
        return subscriberComponent;
    }

    @Bean
    public MessageRegisterProxy messageRegisterProxy(SubscriberConfig config, List<MessageHolder<?>> holders) {
        MessageRegisterProxy messageRegisterProxy = new MessageRegisterProxy(config, holders);
        log.info("===== MessageRegisterProxy initial finish =====");
        return messageRegisterProxy;
    }

    @Bean
    public MessageConsumerProxy messageConsumerProxy(MessageResultModelTool tool, MessageHolderWrap holder, List<MessageHolder<?>> holders) {
        MessageConsumerProxy messageConsumerProxy = new MessageConsumerProxy(tool, holder, holders);
        log.info("===== MessageConsumerProxy initial finish =====");
        return messageConsumerProxy;
    }

    @Bean
    public MessageHolderWrap messageHolderWrap(ApplicationContext context, MessageResultModelTool tool) {
        MessageHolderWrap messageHolderWrap = new MessageHolderWrap(context, tool);
        log.info("===== MessageHolderWrap initial finish =====");
        return messageHolderWrap;
    }

    @Bean
    @ConditionalOnMissingBean(MessageResultModelTool.class)
    public MessageResultModelTool messageResultModelTool() {
        MessageResultModelTool messageResultModelMatchTool = new DefaultMessageResultModelTool();
        log.info("===== MessageResultModelTool initial finish =====");
        return messageResultModelMatchTool;
    }

    @Bean
    @ConditionalOnMissingBean(MessageRepositoryModelTool.class)
    public MessageRepositoryModelTool messageRepositoryModelTool() {
        MessageRepositoryModelTool messageRepositoryModelTool = new DefaultMessageModelRepositoryTool();
        log.info("===== MessageRepositoryModelTool initial finish =====");
        return messageRepositoryModelTool;
    }

    @Bean
    @ConditionalOnMissingBean(MessagePlaceModelTool.class)
    public MessagePlaceModelTool messagePlaceModelTool() {
        MessagePlaceModelTool messagePlaceModelTool = new DefaultMessagePlaceModelTool();
        log.info("===== MessagePlaceModelTool initial finish =====");
        return messagePlaceModelTool;
    }

    @Bean
    @ConditionalOnMissingBean(AmadeusMessageTemplate.class)
    @ConditionalOnBean(Subscriber.class)
    public AmadeusMessageTemplate amadeusMessageTemplate() {
        AmadeusMessageTemplate amadeusMessageTemplate = new AmadeusMessageTemplate();
        log.info("===== AmadeusMessageTemplate initial finish =====");
        return amadeusMessageTemplate;
    }

    @Bean
    @ConditionalOnBean(Subscriber.class)
    public MessageResendFactory messageResendFactory(SubscriberConfig config, MessageRepositoryModelTool repositoryModelTool, MessagePlaceModelTool placeModelTool) {
        MessageResendFactory messageResendFactory = new MessageResendFactory(config, repositoryModelTool, placeModelTool);
        log.info("===== MessageResendFactory initial finish =====");
        return messageResendFactory;
    }

    @Bean
    @ConditionalOnBean(Subscriber.class)
    public MessageAbandonFactory messageAbandonFactory(MessageRepositoryModelTool tool) {
        MessageAbandonFactory messageAbandonFactory = new MessageAbandonFactory(tool);
        log.info("===== MessageAbandonFactory initial finish =====");
        return messageAbandonFactory;
    }
}
